package com.itheima.stock.job.service.impl;

import com.alibaba.excel.util.DateUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.itheima.stock.common.domain.StockInfoConfig;
import com.itheima.stock.job.service.StockTimerService;
import com.itheima.stock.mapper.StockBlockRtInfoMapper;
import com.itheima.stock.mapper.StockMarketIndexInfoMapper;
import com.itheima.stock.mapper.StockMarketLogPriceMapper;
import com.itheima.stock.mapper.StockRtInfoMapper;
import com.itheima.stock.pojo.StockBlockRtInfo;
import com.itheima.stock.pojo.StockMarketIndexInfo;
import com.itheima.stock.pojo.StockMarketLogPrice;
import com.itheima.stock.pojo.StockRtInfo;
import com.itheima.stock.utils.IdWorker;
import com.itheima.util.HttpUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class StockTimerServiceImpl implements StockTimerService {

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;

    @Autowired
    private StockMarketLogPriceMapper stockMarketLogPriceMapper;

    @Autowired
    private StockInfoConfig stockInfoConfig;

    @Autowired
    private StockRtInfoMapper stockRtInfoMapper;

    @Autowired
    private StockBlockRtInfoMapper stockBlockRtInfoMapper;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 注入线程池对象
     */
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    /**
     * 拉取个股流水数据
     */

    /**
     * 拉取板块数据
     */
    @Override
    public void getStockSectorRtIndex() {
        //发送板块数据请求
        String result = restTemplate.getForObject(stockInfoConfig.getBlockUrl(), String.class);
        //响应结果转板块集合数据
        List<StockBlockRtInfo> infos =parse4StockBlock(result);


        // 数据分片保存导数据下 行业板块类目大概50个，每小时查询一次即可
        Lists.partition(infos,20).forEach(list->{
            //20每组，批量插入
            stockBlockRtInfoMapper.insertBatch(list);
        });          //可在最后添加

    }

    /**
     * 解析板块数据
     * @param stockStr
     * @return
     */
    public List<StockBlockRtInfo> parse4StockBlock(String stockStr){
        if (Strings.isNullOrEmpty(stockStr)|| !stockStr.contains("=")){
            return Collections.emptyList();
        }
        String jsonStr = stockStr.substring(stockStr.indexOf("=") + 1);
        HashMap mapInfo = new Gson().fromJson(jsonStr, HashMap.class);
        System.out.println(mapInfo);
        //解析板块数据，封装到实体类中
        List<StockBlockRtInfo> blockList = (List<StockBlockRtInfo>) mapInfo.entrySet().stream().map(entry -> {
            Map.Entry ent = (Map.Entry) entry;
            String infos = (String) ent.getValue();
            String[] infoArray = infos.split(",");
            //板块编码
            String label = infoArray[0];
            //板块行业
            String blockName = infoArray[1];
            //板块公司数量
            Integer companyNum = Integer.valueOf(infoArray[2]);
            //均价
            BigDecimal avgPrice = new BigDecimal(infoArray[3]);
            //涨跌幅度
            BigDecimal priceLimit = new BigDecimal(infoArray[5]);
            //涨跌率
//            BigDecimal updownRate=new BigDecimal(infoArray[5]);
            //总成交量
            Long tradeAmount = Long.valueOf(infoArray[6]);
            //总成交金额
            BigDecimal tradeVolume = new BigDecimal(infoArray[7]);
            //构建板块信息对象
            StockBlockRtInfo blockRtInfo = StockBlockRtInfo.builder().id(idWorker.nextId()+"").label(label)
                    .blockName(blockName).companyNum(companyNum).avgPrice(avgPrice).curTime(new Date())
                    .updownRate(priceLimit).tradeAmount(tradeAmount).tradeVolume(tradeVolume)
                    .build();
            return blockRtInfo;
        }).collect(Collectors.toList());
        return blockList;
    }




    /**
     * 获取个股数据
     * @param code
     * @return
     * @throws ParseException
     */
    public String getStockRtIndex(String code){
        String host = "https://jsapigpcx.market.alicloudapi.com";
        String path = "/stock/query";
        String method = "GET";
        String appcode = "790f648aa62442bfbc4df4fe684bca4d";
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("code", code);
        try {
            HttpResponse response = HttpUtils.doGet(host, path, method, headers, querys);
            System.out.println(response.toString());
            //获取response的body
            String data = EntityUtils.toString(response.getEntity());
            return data;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void insertBatchRt() throws ParseException {
        List stockRtInfo = parseRtStock();
        stockRtInfoMapper.insertBatch(stockRtInfo);
        System.out.println("插入成功");
    }

    /**
     * 解析拉取到的个股数据
     * @return
     * @throws ParseException
     */
    public List<StockRtInfo> parseRtStock() throws ParseException {
        ArrayList<StockRtInfo> stockRtInfoList = new ArrayList<>();
        List<String> stocksList = stockInfoConfig.getStocksList();
        for (String s : stocksList) {
            String stockJson = getStockRtIndex(s);
            Map map = JSON.parseObject(stockJson, Map.class);
            JSONArray resultJsonArray = (JSONArray) map.get("result");
            for (Object o : resultJsonArray) {
                JSONObject jsonObj = (JSONObject) o;
                String name = jsonObj.get("name").toString();
                System.out.println("名称" + name);
                String code = jsonObj.get("code").toString();
                System.out.println("代码： " + code);
                BigDecimal price = new BigDecimal(jsonObj.get("price").toString());
                System.out.println("最新价： " + price);
                BigDecimal lastclosingprice = new BigDecimal(jsonObj.get("lastclosingprice").toString());
                System.out.println("昨收盘价 :" + lastclosingprice);
                String trendnum = jsonObj.get("trendnum").toString();
                System.out.println("数据量: " + trendnum);
                JSONArray trendArray = (JSONArray) jsonObj.get("trend");
                for (Object o1 : trendArray) {
                    StockRtInfo stockRtInfo = new StockRtInfo();
                    String trend = (String) o1;
                    String[] trendArr = trend.split(",");
                    String curTime = trendArr[0];
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                    Date date = dateFormat.parse(curTime);
                    BigDecimal curPrice = new BigDecimal(trendArr[1]);
                    String tradeAmount = trendArr[2];
                    String tradeVolume = trendArr[3];

                    stockRtInfo.setId(idWorker.nextId() + "");
                    stockRtInfo.setStockCode(code);
                    stockRtInfo.setStockName(name);
                    stockRtInfo.setCurTime(date);
                    stockRtInfo.setCurPrice(curPrice);
                    stockRtInfo.setPreClosePrice(lastclosingprice);
                    stockRtInfo.setOpenPrice(lastclosingprice);
                    stockRtInfo.setMaxPrice(new BigDecimal(999.00));
                    stockRtInfo.setMinPrice(new BigDecimal(1.0));
                    stockRtInfo.setTradeAmount(tradeAmount);
                    stockRtInfo.setTradeVolume(tradeVolume);
                    stockRtInfoList.add(stockRtInfo);
                }

            }
        }
        System.out.println(stockRtInfoList);
        return stockRtInfoList;
    }

    @Override
    public void insertBatch() throws ParseException {
        Map<String,List> map = parseResultJson();
        List<StockMarketIndexInfo> stockIndexInfoList = map.get("stockIndexInfoList");
        List<StockMarketLogPrice> stockLogList = map.get("stockLogList");
        stockMarketIndexInfoMapper.insertBatch(stockIndexInfoList);
        stockMarketLogPriceMapper.insertBatch(stockLogList);
    }

    public Map parseResultJson() throws ParseException {
        Map<String, List> resultMap = new HashMap();
        //String dapanJson = JsonConstance.dapanData;
        String dapanJson = getInnerMarketInfo();
        // 将json字符串转存到Map集合中
        Map map = JSON.parseObject(dapanJson, Map.class);
        // 大盘结果数据
        JSONArray resultJsonArray = (JSONArray) map.get("result");
        // 定义集合用于收集大盘分钟趋势数据
        List<StockMarketIndexInfo> stockIndexInfoList = new ArrayList<>();
        // 定义集合用于收集大盘基础数据 前收盘价 今开盘价
        List<StockMarketLogPrice> stockLogList = new ArrayList<>();
        // 遍历大盘数据数组
        for (Object resultJson : resultJsonArray) {
            // 将获取的元素转成Json对象
            JSONObject jsonObj =  (JSONObject)resultJson;
            // 大盘名称
            String name = jsonObj.get("name").toString();
            System.out.println("--------------"+name+"-------------");
            System.out.println("大盘名称 "+name);
            // 大盘代码
            String code = jsonObj.get("code").toString();
            System.out.println("大盘代码 "+code);
            // 处理大盘代码
            if (name.equals("上证指数")){
                code = "s_sh"+code;
            }else if(name.equals("深证成指")){
                code = "s_sz"+code;
            }else {
                code = "s_qt"+code;
            }
            // 大盘当前价格
            BigDecimal price = new BigDecimal(jsonObj.get("price").toString());
            System.out.println("大盘当前价格 "+price);
            // 大盘开盘价格
            BigDecimal openningprice = new BigDecimal(jsonObj.get("openningprice").toString());
            System.out.println("大盘开盘 "+openningprice);
            // 收盘价格
            BigDecimal lastclosingprice = new BigDecimal(jsonObj.get("lastclosingprice").toString());
            System.out.println("大盘前收盘价格 "+lastclosingprice);
            // 返回的趋势数据条数
            String trendnum = jsonObj.get("trendnum").toString();
            System.out.println("大盘趋势数据数量 "+trendnum);
            // 当前日期
            Date updatetime = new DateTime(Long.parseLong(jsonObj.get("updatetime") + "000")).toDate();
            System.out.println("当前时间 "+updatetime);
            JSONArray trendArray = (JSONArray) jsonObj.get("trend");
            System.out.println("大盘趋势数据 "+trendArray);
            for (Object o : trendArray) {
                StockMarketIndexInfo stockMarketIndexInfo = new StockMarketIndexInfo();
                // 将每一分钟生成的数据转成字符串
                String trend = (String)o;
                // 处理
                String[] trendArr = trend.split(",");
                String curTime = trendArr[0];
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                Date date = dateFormat.parse(curTime);
                BigDecimal curPrice = new BigDecimal(trendArr[1]);
                String tradeAccount = trendArr[2];
                String tradeVolume = trendArr[3];
                //System.out.println(curTime+" : "+curPrice+" : "+tradeAccount+" : "+tradeVolume);
                stockMarketIndexInfo.setId(idWorker.nextId()+"");
                stockMarketIndexInfo.setMarkId(code);
                stockMarketIndexInfo.setCurTime(date);
                stockMarketIndexInfo.setMarkName(name);
                stockMarketIndexInfo.setCurPoint(curPrice);
                // 当前价格 - 前一日收盘价格
                stockMarketIndexInfo.setCurrentPrice(curPrice.subtract(lastclosingprice)); // 涨跌额
                // (当前价格 - 前一日收盘价格)/前一日收盘价格
                stockMarketIndexInfo.setUpdownRate((curPrice.subtract(lastclosingprice)).divide(lastclosingprice,4,BigDecimal.ROUND_HALF_UP)); // 涨跌幅
                stockMarketIndexInfo.setTradeAccount(tradeAccount);
                stockMarketIndexInfo.setTradeVolume(tradeVolume);
                stockIndexInfoList.add(stockMarketIndexInfo);
            }
            // 大盘前收盘和今开盘数据
            StockMarketLogPrice stockMarketLogPrice = new StockMarketLogPrice();
            stockMarketLogPrice.setId(idWorker.nextId()+"");
            stockMarketLogPrice.setMarketCode(code);
            stockMarketLogPrice.setCurDate(updatetime);
            stockMarketLogPrice.setPreClosePrice(lastclosingprice);
            stockMarketLogPrice.setOpenPrice(openningprice);
            stockLogList.add(stockMarketLogPrice);
        }
        System.out.println(stockIndexInfoList);
        System.out.println("插入成功...");
        resultMap.put("stockIndexInfoList",stockIndexInfoList);
        resultMap.put("stockLogList",stockLogList);
        return resultMap;
    }

    @Override
    public String getInnerMarketInfo() {
        // 域名
        String host = "https://jsszzs.market.alicloudapi.com";
        // 请求接口路径
        String path = "/stockindex/sh";
        // 请求方式
        String method = "GET";
        // 自己购买的接口code
        String appcode = "790f648aa62442bfbc4df4fe684bca4d";
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        Map<String, String> querys = new HashMap<String, String>();
        try {
            /**
             * todo:重要提示如下:
             * HttpUtils请从
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
             * 下载
             *
             * 相应的依赖请参照
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
             */
            HttpResponse response = HttpUtils.doGet(host, path, method, headers, querys);
            //System.out.println(response.toString());
            //获取response的body
            String dapanJson = EntityUtils.toString(response.getEntity());
            //System.out.println(dapanJson);
            return dapanJson;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


}
